Skip to content

feat: express NHI + AI-agent ontology in the config schema [DRAFT / DO-NOT-MERGE]#136

Merged
pquerna merged 2 commits into
mainfrom
nhi/config-schema-ontology
Jun 5, 2026
Merged

feat: express NHI + AI-agent ontology in the config schema [DRAFT / DO-NOT-MERGE]#136
pquerna merged 2 commits into
mainfrom
nhi/config-schema-ontology

Conversation

@c1-squire-dev

@c1-squire-dev c1-squire-dev Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

DRAFT / DO-NOT-MERGE — additive enablement work for review.

What

Lets a baton-sql config author declare the non-human-identity (NHI) ontology and AI agents directly in the YAML config grammar; the engine translates these declarations into the corresponding baton-sdk v2 traits/annotations.

This mirrors the NHI parity baton-axiomatic recently reached (PRs #145–#148), expressed through baton-sql's config grammar instead of axiomatic's TypeScript author surface. The SDK traits emitted are identical.

Mappings

Capability Config (under map:) Emits Net-new?
K1 secret / credential traits.secret.{credential_type, credential_detail, expires_at, last_used_at} SecretTrait + TRAIT_SECRET new
K2 service / system account traits.user.account_type (service|system|human) UserTrait.account_type already supported (resources.go); covered with a test
K3 non-human identity non_human_identity.{nhi_type, nhi_detail} NonHumanIdentityTrait new
AI agent traits.agent.{status, identity_resource_type, identity_resource_id, profile} AgentTrait + TRAIT_AGENT new

Enum values

  • credential_type: static_secret | asymmetric_key | certificate (no api_key, per the SDK enum).
  • nhi_type: app_registration | assumable_role | managed_identity.
  • agent.status: ready (active/enabled) | disabled (inactive) | deleted.

Design notes

  • NHI is kind-agnostic. The SDK's WithNHIType is documented as combinable with any resource trait, and there is no ResourceType_TRAIT_NHI. So non_human_identity is a sibling of traits (not a member of it) and is applied in mapResource after the primary trait — a resource can be an app/role/user and a non-human identity, or an NHI with no other trait.
  • Secret and Agent are primary traits, declared under map.traits.* like user/app, wired through fetchTraits/mapTraits and advertised via extractTraits (TRAIT_SECRET / TRAIT_AGENT).
  • baton-sdk stays at v0.12.4 — it already supersedes the v0.11.1 release that introduced these traits; all symbols are vendored. No dependency change.

Graceful degradation

Every new field is optional. Configs that don't use them parse and sync identically (existing examples untouched). Unknown enum strings log a warning and fall back to UNSPECIFIED rather than failing the sync.

Tests / gates

  • pkg/bsql/nhi_test.go — a config exercising each mapping asserts the emitted traits (incl. app+NHI co-existence and a "no annotations by default" graceful-degradation case), plus a parse test for the shipped example.
  • examples/nhi-example.yml — documented reference exercising all four.
  • go build ./... ✅ · go test ./... ✅ · golangci-lint run — 0 new issues in changed files (4 pre-existing findings live in untouched files: provisioning.go, query_test.go, user_syncer_test.go).

🤖 Generated with Claude Code


🏰 Opened from a Squire environment: fierce-cobra-24918
Task: f6700d26-0f2a-4581-867c-b4b39ecfa2fb

Open this environment in Squire

Lets a config author declare the non-human-identity ontology and AI agents
directly in the YAML grammar; the engine emits the matching baton-sdk traits.
Mirrors the NHI parity baton-axiomatic reached (PRs #145-#148), expressed
through baton-sql's config grammar instead of axiomatic's TS author surface.

- K1 secret/credential: map.traits.secret {credential_type, credential_detail,
  expires_at, last_used_at} -> SecretTrait (TRAIT_SECRET).
- K2 service/system account: map.traits.user.account_type (already supported)
  -> UserTrait.account_type; covered with a test.
- K3 non-human identity: map.non_human_identity {nhi_type, nhi_detail} ->
  NonHumanIdentityTrait, kind-agnostic (sibling of traits; co-exists with any
  or no primary trait).
- AI agent: map.traits.agent {status, identity_resource_type,
  identity_resource_id, profile} -> AgentTrait (TRAIT_AGENT).

Additive and gracefully degrading: every field is optional, unknown enum
strings warn and fall back to UNSPECIFIED, existing configs are unchanged.
baton-sdk stays at v0.12.4 (already supersedes the v0.11.1 that introduced
these traits). Adds nhi_test.go and examples/nhi-example.yml.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: feat: express NHI + AI-agent ontology in the config schema [DRAFT / DO-NOT-MERGE]

Blocking Issues: 0 | Suggestions: 0 | Threads Resolved: 0
Review mode: incremental since bf00fc05
View review run

Review Summary

The new commit adds a //nolint:gosec directive to nhi_test.go to silence G101 false positives on string literals used as NHI trait config keys. This is a reasonable suppression — the flagged strings are config field names like credential_type, not actual secrets. The full PR diff (config structs, trait mapping functions, trait extraction, tests, and example YAML) was scanned for security and correctness issues with no findings.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

None.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

CI's golangci-lint v2.11.4 flags the secret trait-config string literals as
potential hardcoded credentials. Apply the same file-level //nolint:gosec
convention used by user_syncer_test.go.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking issues found.

@pquerna pquerna marked this pull request as ready for review June 5, 2026 19:39
@pquerna pquerna requested a review from a team June 5, 2026 19:39
@pquerna pquerna merged commit 9d19d7a into main Jun 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant